/*
 * Copyright 2010-2012 Susanta Tewari. <freecode4susant@users.sourceforge.net>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/*
* RandomUtil.java
*
* Created on November 21, 2007, 8:32 PM
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
 */
package javautil.lang;

import javautil.collections.ArrayUtil;
import javautil.io.LogUtil;

/**
 *
 * @author stewari1
 */
public class RandomUtil {

    public static void main(String[] args) {

        int[] order = {
            1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
        };

        for (int i = 0; i < 5; i++) {

            LogUtil.print(randomBlockReversal(order));
        }
    }

    /**
     * swaps array elements i and j
     *
     * @param a description
     * @param i description
     * @param j description
     */
    private static void exch(Object[] a, int i, int j) {

        Object swap = a[i];

        a[i] = a[j];
        a[j] = swap;
    }

    /**
     * take as input an array of strings and rearrange them in random order
     *
     * @param a description
     *
     * @return description
     */
    private static Object[] shuffle(Object[] a) {

        int N = a.length;

        for (int i = 0; i < N; i++) {

            int r = i + (int) (Math.random() * (N - i));    // between i and N-1

            exch(a, i, r);
        }

        return a;
    }

    public static int[] shuffle(int[] a) {
        return ArrayUtil.getIntegerArray((Integer[]) shuffle(ArrayUtil.getIntegerArray(a)));
    }

    public static int[] randomBlockReversal(int[] oldOrder) {

        int[] newOrder = oldOrder.clone();


        // choose 2 end points (i and j) randomly on the length of the order
        int i = (int) (Math.random() * newOrder.length);
        int j = (int) (Math.random() * newOrder.length);

        i = Math.min(i, j);
        j = Math.max(i, j);


        // reverse the block between i and j, including i and j.
        for (int k = i; k <= j; k++) {

            newOrder[k] = oldOrder[j - k + i];
        }

        return newOrder;
    }
}
